home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / othergnu / ispell.zoo / ispell.c < prev    next >
C/C++ Source or Header  |  1990-04-19  |  27KB  |  1,370 lines

  1. /* -*- Mode:Text -*- */
  2.  
  3. #define MAIN
  4.  
  5. /*
  6.  * ispell.c - An interactive spelling corrector.
  7.  *
  8.  * Copyright (c), 1983, by Pace Willisson
  9.  * Permission for non-profit use is hereby granted.
  10.  * All other rights reserved.
  11.  *
  12.  * 1987, Robert McQueer, added:
  13.  *    -w option & handling of extra legal word characters
  14.  *    -d option for alternate dictionary file
  15.  *    -p option & WORDLIST variable for alternate personal dictionary
  16.  *    -x option to suppress .bak files.
  17.  *    8 bit text & config.h parameters
  18.  * 1987, Geoff Kuenning, added:
  19.  *    -c option for creating suffix suggestions from raw words
  20.  *    suffixes in personal dictionary file
  21.  *    hashed personal dictionary file
  22.  *    -S option for unsorted word lists
  23.  * 1987, Greg Schaffer, added:
  24.  *    -T option (for TeX and LaTeX instead of troff) [later changed to -t]
  25.  *       passes over \ till next whitespace.
  26.  *       does not recognize % (comment)
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <ctype.h>
  31. #include <sys/param.h>
  32. #if defined(USG) || defined(atarist)
  33. #include <sys/types.h>
  34. #endif
  35. #include <sys/stat.h>
  36. #include "config.h"
  37. #include "ispell.h"
  38. #include "version.h"
  39.  
  40. #define ISTEXTERM(c)   (((c) == '{') || \
  41.             ((c) == '}') || \
  42.             ((c) == '[') || \
  43.             ((c) == ']'))
  44.  
  45. FILE *infile;
  46. FILE *outfile;
  47.  
  48. char hashname[MAXPATHLEN];
  49.  
  50. extern struct dent *treeinsert();
  51. extern char *upcase ();
  52. extern char *lowcase ();
  53.  
  54. extern char *rindex();
  55. extern char *strcpy ();
  56.  
  57. /*
  58. ** we use extended character set range specifically to allow intl.
  59. ** character set characters.  We are being REALLY paranoid about indexing
  60. ** this array - explicitly cast into unsigned INTEGER, then mask
  61. ** If NO8BIT is set, text will be masked to ascii range.
  62. */
  63. static int Trynum;
  64. #ifdef NO8BIT
  65. static char Try[128];
  66. static char Checkch[128];
  67. #define iswordch(X) (Checkch[((unsigned)(X))&0x7f])
  68. #else
  69. static char Try[256];
  70. static char Checkch[256];
  71. #define iswordch(X) (Checkch[((unsigned)(X))&0xff])
  72. #endif
  73.  
  74. static int sortit = 1;
  75.  
  76. givehelp ()
  77. {
  78.     erase ();
  79.     printf ("Whenever a word is found that is not in the dictionary,\r\n");
  80.     printf ("it is printed on the first line of the screen.  If the dictionary\r\n");
  81.     printf ("contains any similar words, they are listed with a single digit\r\n");
  82.     printf ("next to each one.  You have the option of replacing the word\r\n");
  83.     printf ("completely, or choosing one of the suggested words.\r\n");
  84.     printf ("\r\n");
  85.     printf ("Commands are:\r\n\r\n");
  86.     printf ("R       Replace the misspelled word completely.\r\n");
  87.     printf ("Space   Accept the word this time only\r\n");
  88.     printf ("A       Accept the word for the rest of this file.\r\n");
  89.     printf ("I       Accept the word, and put it in your private dictionary.\r\n");
  90.     printf ("0-9     Replace with one of the suggested words.\r\n");
  91.     printf ("L       Look up words in system dictionary.\r\n");
  92.     printf ("Q       Write the rest of this file, ignoring misspellings, ");
  93.     printf (         "and start next file.\r\n");
  94.     printf ("X       Exit immediately.  Asks for confirmation.  ");
  95.     printf (         "Leaves file unchanged.\r\n");
  96.     printf ("!       Shell escape.\r\n");
  97.     printf ("^L      Redraw screen.\r\n");
  98.     printf ("\r\n\r\n");
  99.     printf ("-- Type space to continue --");
  100.     fflush (stdout);
  101.     while (getchar () != ' ')
  102.         ;
  103. }
  104.  
  105.  
  106. char *getline();
  107.  
  108. int cflag = 0;
  109. int lflag = 0;
  110. int incfileflag = 0;
  111. int aflag = 0;
  112. int fflag = 0;
  113. #if !defined(USG) && !defined(atarist)
  114. int sflag = 0;
  115. #endif
  116. int xflag = 0;
  117. int tflag = 0;
  118.  
  119. char *askfilename;
  120.  
  121. static char *Cmd;
  122.  
  123. usage ()
  124. {
  125.     fprintf (stderr,
  126.         "Usage: %s [-dfile | -pfile | -wchars | -t | -x | -S] file .....\n",
  127.         Cmd);
  128.     fprintf (stderr,
  129.         "       %s [-dfile | -pfile | -wchars | -t] -l\n",
  130.         Cmd);
  131. #if !defined(USG) && !defined(atarist)
  132.     fprintf (stderr,
  133.         "       %s [-dfile | -pfile | -ffile | -t | -s] {-a | -A}\n",
  134.         Cmd);
  135. #else
  136.     fprintf (stderr,
  137.         "       %s [-dfile | -pfile | -ffile | -t] {-a | -A}\n",
  138.         Cmd);
  139. #endif
  140.     fprintf (stderr, "       %s [-wchars] -c\n", Cmd);
  141.     fprintf (stderr, "       %s -v\n", Cmd);
  142.     exit (1);
  143. }
  144.  
  145. static initckch()
  146. {
  147.     register int c;
  148.  
  149.     Trynum = 0;
  150. #ifdef NO8BIT
  151.     for (c = 0; c < 128; ++c) {
  152. #else
  153.     for (c = 0; c < 256; ++c) {
  154. #endif
  155.         if (myalpha((char) c)) {
  156.             Checkch[c] = (char) 1;
  157.             if (myupper((char) c)) {
  158.                 Try[Trynum] = (char) c;
  159.                 ++Trynum;
  160.             }
  161.         }
  162.         else
  163.             Checkch[c] = (char) 0;
  164.     }
  165. }
  166.  
  167. main (argc, argv)
  168. char **argv;
  169. {
  170.     char *p;
  171.     char *cpd;
  172.     char num[4];
  173.     unsigned mask;
  174.     static char outbuf[BUFSIZ];
  175.     extern char *getenv();
  176.  
  177.     Cmd = *argv;
  178.  
  179.     initckch();
  180. #ifdef atarist
  181.     if((p = getenv("LIB")) != NULL)
  182.         sprintf(hashname,"%s/%s",p,DEFHASH);
  183.     else
  184. #endif
  185.         sprintf(hashname,"%s/%s",LIBDIR,DEFHASH);
  186.  
  187.     cpd = NULL;
  188.  
  189.     argv++;
  190.     argc--;
  191.     while (argc && **argv == '-') {
  192.         switch ((*argv)[1]) {
  193.         case 'v':
  194.             printf ("%s\n", Version_ID);
  195.             exit (0);
  196.         case 't':
  197.             tflag++;
  198.             break;
  199.         case 'A':
  200.             incfileflag = 1;
  201.             aflag = 1;
  202.             break;
  203.         case 'a':
  204.             aflag++;
  205.             break;
  206.         case 'c':
  207.             cflag++;
  208.             lflag++;
  209.             break;
  210.         case 'x':
  211.             xflag++;
  212.             break;
  213.         case 'f':
  214.             fflag++;
  215.             p = (*argv)+2;
  216.             if (*p == '\0') {
  217.                 argv++; argc--;
  218.                 if (argc == 0)
  219.                     usage ();
  220.                 p = *argv;
  221.             }
  222.             askfilename = p;
  223.             break;
  224.         case 'l':
  225.             lflag++;
  226.             break;
  227. #if !defined(USG) && !defined(atarist)
  228.         case 's':
  229.             sflag++;
  230.             break;
  231. #endif
  232.         case 'S':
  233.             sortit = 0;
  234.             break;
  235.         case 'p':
  236.             cpd = (*argv)+2;
  237.             if (*cpd == '\0') {
  238.                 argv++; argc--;
  239.                 if (argc == 0)
  240.                     usage ();
  241.                 cpd = *argv;
  242.             }
  243.             break;
  244.         case 'd':
  245.             p = (*argv)+2;
  246.             if (*p == '\0') {
  247.                 argv++; argc--;
  248.                 if (argc == 0)
  249.                     usage ();
  250.                 p = *argv;
  251.             }
  252.             if (*p == '/')
  253.                 strcpy(hashname,p);
  254.             else
  255.                 sprintf(hashname,"%s/%s",LIBDIR,p);
  256.             break;
  257.         case 'w':
  258.             num[3] = '\0';
  259. #ifdef NO8BIT
  260.             mask = 0x7f;
  261. #else
  262.             mask = 0xff;
  263. #endif
  264.             p = (*argv)+2;
  265.             if (*p == '\0') {
  266.                 argv++; argc--;
  267.                 if (argc == 0)
  268.                     usage ();
  269.                 p = *argv;
  270.             }
  271.             while (Trynum <= mask && *p != '\0') {
  272.                 if (*p != 'n'  &&  *p != '\\') {
  273.                     Checkch[((unsigned)(*p))&mask] = (char) 1;
  274.                     Try[Trynum] = *p & mask;
  275.                     ++p;
  276.                 }
  277.                 else {
  278.                     ++p;
  279.                     num[0] = '\0'; 
  280.                     num[1] = '\0'; 
  281.                     num[2] = '\0'; 
  282.                     num[3] = '\0';
  283.                     if (isdigit (p[0]))
  284.                         num[0] = p[0];
  285.                     if (isdigit (p[1]))
  286.                         num[1] = p[1];
  287.                     if (isdigit (p[2]))
  288.                         num[2] = p[2];
  289.                     if (p[-1] == 'n') {
  290.                         p += strlen (num);
  291.                         num[0] = atoi (num);
  292.                     }
  293.                     else {
  294.                         p += strlen (num);
  295.                         if (num[0])
  296.                             num[0] -= '0';
  297.                         if (num[1]) {
  298.                             num[0] <<= 3;
  299.                             num[0] += num[1] - '0';
  300.                         }
  301.                         if (num[2]) {
  302.                             num[0] <<= 3;
  303.                             num[0] += num[2] - '0';
  304.                         }
  305.                     }
  306.                     Try[Trynum] = num[0] & mask;
  307.                     Checkch[num[0] & mask] = 1;
  308.                 }
  309.                 ++Trynum;
  310.             }
  311.             break;
  312.         default:
  313.             usage();
  314.         }
  315.         argv++; argc--;
  316.     }
  317.  
  318.     if (!argc && !lflag && !aflag)
  319.         usage ();
  320.  
  321.     if (linit () < 0)
  322.         exit (0);
  323.  
  324.     treeinit (cpd);
  325.  
  326.     if (aflag) {
  327.         askmode ();
  328.         exit (0);
  329.     }
  330.  
  331.     setbuf (stdout, outbuf);
  332.     if (lflag) {
  333.         infile = stdin;
  334.         checkfile ();
  335.         exit (0);
  336.     }
  337.  
  338.     terminit ();
  339.  
  340.     while (argc--)
  341.         dofile (*argv++);
  342.  
  343.     done ();
  344. }
  345.  
  346. char firstbuf[BUFSIZ], secondbuf[BUFSIZ];
  347. char *currentchar;
  348. char token[BUFSIZ];
  349.  
  350. int quit;
  351.  
  352. char *currentfile = NULL;
  353.  
  354. dofile (filename)
  355. char *filename;
  356. {
  357.     int c;
  358.     char    bakfile[256];
  359.     struct stat statbuf;
  360.     char *cp;
  361.  
  362.     currentfile = filename;
  363.  
  364.     if ((infile = fopen (filename, "r")) == NULL) {
  365.         fprintf (stderr, "Can't open %s\r\n", filename);
  366.         sleep (2);
  367.         return;
  368.     }
  369.  
  370.     if (access (filename, 2) < 0) {
  371.         fprintf (stderr, "Can't write to %s\r\n", filename);
  372.         sleep (2);
  373.         return;
  374.     }
  375.  
  376.     fstat (fileno (infile), &statbuf);
  377. #ifdef atarist
  378.     {
  379.       char *p, c;
  380.       extern char *getenv();
  381.  
  382.       if((p = getenv("TEMP")) != NULL)
  383.       {
  384.           strcpy(tempfile, p);
  385.           c = p[(strlen(p) - 1)];
  386.           if((c != '/') || (c != '\\'))
  387.         strcat(tempfile,"/");
  388.       }
  389.     }
  390. #endif    
  391.     strcpy(tempfile, TEMPNAME);
  392.     mktemp (tempfile);
  393.     chmod (tempfile, statbuf.st_mode);
  394.     if ((outfile = fopen (tempfile, "w")) == NULL) {
  395.         fprintf (stderr, "Can't create %s\r\n", tempfile);
  396.         sleep (2);
  397.         return;
  398.     }
  399.  
  400.     quit = 0;
  401.  
  402.     /* See if the file is a .tex file.  If so, set the appropriate flag. */
  403.     if ((cp = rindex (filename, '.')) != NULL  &&  strcmp (cp, ".tex") == 0)
  404.         tflag = 1;
  405.     checkfile